/*
 * Created: Author: Aléx Carvalho / Date: Mar 2, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-11 04:28:43 +0000 (Thu, 11 Jun 2015) $
 */
package com.cpm.wrapper;

import com.cpm.ServiceLocator;
import com.cpm.entities.Competence;
import com.cpm.entities.Competence_;
import com.cpm.entities.Indicator;
import com.cpm.repository.Filter;
import java.time.LocalDate;
import java.time.Month;
import java.time.Year;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class CompetenceList extends WrapperList<Competence> {

    private final Indicator indicator;

    private Map<String, Competence> cacheByYearAndMonth = null;

    public CompetenceList(Indicator source) {
        this(source, null);
    }

    public CompetenceList(Indicator source, List<Competence> competences) {
        this.indicator = source;
        this.list = competences;
    }
    
    public Competence getCompetenceByLocalDate(LocalDate date) {
        return getCompetenceByYearAndMonth(Year.of(date.getYear()), date.getMonth());
    }
    
    public Competence getCompetenceByYearAndMonth(Year year, Month month) {
        SolidObjects.notNullValues(year, month);
        if (cacheByYearAndMonth == null) {

            Function<Competence, String> key = (Competence c) -> {
                LocalDate period = c.getPeriod();
                return period.getMonth() + "/" + period.getYear();
            };

            cacheByYearAndMonth = getItems().stream().collect(Collectors.toMap(key, Function.identity()));
        }

        return cacheByYearAndMonth.get(month.toString() + "/" + year.toString());
    }

    public List<Competence> getCompetencesSmaller(Competence c) {
        return getCompetencesSmaller(Year.of(c.getPeriod().getYear()), c.getPeriod().getMonth());
    }
    
    public List<Competence> getCompetencesSmaller(Year year, Month month) {
        return getItems().stream().filter(c -> c.getPeriod().isBefore(LocalDate.of(year.getValue(), month, month.minLength())))
                .collect(Collectors.toList());
    }
    
    public List<Competence> getCompetencesLarger(Competence c) {
        return getCompetencesLarger(Year.of(c.getPeriod().getYear()), c.getPeriod().getMonth());
    }

    public List<Competence> getCompetencesLarger(Year year, Month month) {
        LocalDate dt = LocalDate.of(year.getValue(), month, 1).with(TemporalAdjusters.lastDayOfMonth());
        return getItems().stream().filter(c -> c.getPeriod().isAfter(dt))
                .collect(Collectors.toList());
    }

    @Override
    public List<Competence> getItems() {
        if (list == null) {
            Filter filter = ServiceLocator.getFilter().andEquals(Competence_.indicator, indicator.getId());

            list = filter.getResultList(Competence.class);
        }
        return list;
    }
}
